package top.porchwood.jweb.mcsm.controller;

import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import top.porchwood.jweb.mcsm.service.EmailService;
import top.porchwood.jweb.mcsm.service.MCSMUserDetailService;
import top.porchwood.jweb.mcsm.struct.MCSMUserDetails;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.sql.ResultSet;
import java.sql.Time;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

@Controller
public class UserAuthController {
    @Autowired
    JdbcTemplate jdbc;
    @PostMapping("/user/logged")
    private void onUserLogged(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setStatus(200);
        response.getWriter().write("登录成功");
    }

    @PostMapping("/user/register")
    private void onUserRegister(
            Principal principal,
            @RequestParam("username") String userName,
            @RequestParam("password") String password,
            @RequestParam("email") String email,
            @RequestParam("auth_code") String code,
            HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        if (principal != null) {
            response.sendError(403, "你已经登陆过了！不能再次注册");
            return;
        }
        if (!Pattern.matches("^[A-Za-z]+[A-Za-z0-9_]{6,20}$", userName)) {
            response.sendError(400, "用户名不合理，只能是大小写字母与数字和下划线并以字母开头，且长度为6~20之间");
        }
        if (MCSMUserDetailService.findUser(userName) != null) {
            response.sendError(409, "当前用户名已被注册了");
            return;
        }
        if (!Pattern.matches("^[A-Za-z0-9_]{6,20}@[A-Za-z0-9_]+\\.[A-Za-z0-9_]+$", userName)) {
            response.sendError(400, "不合理的邮箱格式");
        }
        if (MCSMUserDetailService.findUser(email) != null) {
            response.sendError(409, "当前邮箱已被注册了");
            return;
        }
        if (!Pattern.matches("^[A-Za-z0-9.,_+=#$@\\-]{8,40}$", password)) {
            response.sendError(400, "密码不合理，只能是大小写字母、数字和部分符号，且长度为8~40之间");
            return;
        }
        if (code == null) {
            if (!EmailService.getInstance().sendEmailAuthCode(email, userName)) {
                response.sendError(500,"未知错误，验证码发送失败，请寻找管理员解决");
            }
            else {
                response.setStatus(200);
                response.getWriter().write("发送成功，请前往邮箱查找验证码");
            }
        } else {
            String dbCode;
            long dbTime;
            //ResultSet data = jdbc.query("", );
        }

    }

    @RequestMapping("/user/logout")
    private void onUserTryLogout(Principal principal, HttpServletRequest request, HttpServletResponse response) throws
            IOException {
        response.setCharacterEncoding("UTF-8");
        if (principal == null) {
            response.sendError(403, "你当前没有登录!");
            return;
        }
        //request.getSession().removeAttribute(principal.getName());
        request.getSession().invalidate();
        response.setStatus(200);
        response.getWriter().write("退出登录成功!");
    }

    @RequestMapping("/user/loginFailed")
    private void onUserLoginFailed(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.sendError(403, "登录失败，用户名或密码错误");
    }

    @RequestMapping("/user/info")
    private void onUserTryGetInfo(Principal principal, HttpServletRequest request, HttpServletResponse response) throws
            IOException {
        response.setCharacterEncoding("UTF-8");
        if (principal == null) {
            response.setStatus(200);
            response.getWriter().write("""
                    {
                        "status": "noUser",
                        "message": "当前没有登录",
                        "content": "null"
                    }
                    """);
            return;
        }
        response.setStatus(200);
        response.getWriter().write("""
                {
                    "status": "OK",
                    "message": "获取账户信息成功",
                    "content": %s
                }
                """.formatted(new Gson().toJson(new User(principal.getName()))));
    }

    @RequestMapping("/user/headImage")
    private String onUserGetHeadImage(Principal principal) {
        if (principal == null) {
            return "redirect:../img/user/normal_100.png";
        }
        //todo 更改为用户的头像地址
        return "redirect:../img/user/normal_100.png";
    }

    @RequestMapping("/user/banner")
    private String onUserGetBanner() {
        //todo 更改为用户的头像地址
        return "redirect:./img/banner.png";
    }

    public static class User {
        public String name;
        public String nick;
        public String uuid;

        public User(String name) {
            this.name = name;
            this.nick = name;
        }

        public User(String name, String nick) {
            this(name);
            this.nick = nick;
        }

        public static User getUser(Principal principal) {
            MCSMUserDetails ud = MCSMUserDetailService.findUser(principal.getName());
            if (ud == null) return null;
            return new User(ud.getUsername(), ud.getNick()).setUuid(ud.getUUID());
        }

        public User setName(String name) {
            this.name = name;
            return this;
        }

        public User setNick(String nick) {
            this.nick = nick;
            return this;
        }

        public User setUuid(String uuid) {
            this.uuid = uuid;
            return this;
        }
    }

    private static class AuthCode {
        private String EMAIL;
        private String NAME;
        private long REQ_TIME;
        private String CODE;

        public String getEmail() {
            return EMAIL;
        }

        public String getName() {
            return NAME;
        }

        public boolean isExpired() {
            return new Date().getTime() - REQ_TIME <= 300000; // 5分钟
        }

        public String getCode() {
            return CODE;
        }

        public static AuthCode toObject(Map map) {
            //时间要转为long
            map.put("REQ_TIME", ((LocalDateTime) map.get("REQ_TIME")).toEpochSecond(ZoneOffset.UTC));
            return new Gson().fromJson(new Gson().toJson(map), AuthCode.class);
        }
    }
}
